package com.huashi.dealer.core.task;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
// import com.baomidou.mybatisplus.extension.plugins.pagination.Page; // 已移除，不再需要分页
import com.huashi.dealer.core.util.ApiHttpClient;
import com.huashi.dealer.core.util.RedisUtil;
import com.huashi.dealer.commonEntity.Goods;
import com.huashi.dealer.commonEntity.GoodsSku;
import com.huashi.dealer.modular.business.goods.mapper.GoodsMapper;
import com.huashi.dealer.modular.business.goods.mapper.GoodsSkuMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
// import org.springframework.scheduling.annotation.Scheduled; // 已注释，需要时取消注释
// import org.springframework.stereotype.Component; // 已注释，需要时取消注释

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 库存同步定时任务
 * 每小时同步一次商品库存，避免频繁调用三方API
 *
 * @author 系统自动生成
 */
@Slf4j
//@Component
public class StockSyncTask {

    @Autowired
    private GoodsMapper goodsMapper;

    @Autowired
    private GoodsSkuMapper goodsSkuMapper;

    @Autowired
    private RedisUtil redisUtil;

    // @Autowired
    // private org.springframework.data.redis.core.RedisTemplate<String, Object> redisTemplate; // 已移除，不再需要分布式锁

    // 配置常量
    private static final String SYSTEM_NAME = "crm_system";
    private static final long SYNC_INTERVAL_MINUTES = 60; // 同步间隔：1小时
    // private static final int BATCH_SIZE = 50; // 每批处理数量 - 已移除，不再需要分页
    // private static final long LOCK_TIMEOUT_SECONDS = 300; // 锁超时时间：5分钟 - 已移除，不再需要分布式锁

    // API_KEY缓存，避免每次都调用
    private volatile String cachedApiKey;
    private volatile long apiKeyCacheTime;

    /**
     * 获取API_KEY（带缓存机制）
     *
     * @return API密钥
     */
    private String getApiKey() {
        // 检查缓存是否有效（30分钟缓存）
        long currentTime = System.currentTimeMillis();
        if (cachedApiKey != null && (currentTime - apiKeyCacheTime) < 30 * 60 * 1000) {
            return cachedApiKey;
        }

        try {
            // 调用API获取密钥信息
            String url = "/v1/api/keys/system/" + SYSTEM_NAME;
            String response = ApiHttpClient.get(url, SYSTEM_NAME, null);

            if (response == null || response.trim().isEmpty()) {
                log.error("获取API_KEY失败：响应为空");
                return null;
            }

            // 解析响应
            JSONObject jsonObject = JSONUtil.parseObj(response);
            if (jsonObject == null) {
                log.error("获取API_KEY失败：响应格式错误 - {}", response);
                return null;
            }

            // 检查响应状态
            Integer code = jsonObject.getInt("code");
            if (code == null || code != 200) {
                log.error("获取API_KEY失败：API返回错误码 {} - {}", code, jsonObject.getStr("msg"));
                return null;
            }

            // 提取API_KEY
            JSONObject data = jsonObject.getJSONObject("data");
            if (data == null) {
                log.error("获取API_KEY失败：响应数据为空");
                return null;
            }

            String apiKey = data.getStr("apiKey");
            if (apiKey == null || apiKey.trim().isEmpty()) {
                log.error("获取API_KEY失败：API_KEY为空");
                return null;
            }

            // 更新缓存
            cachedApiKey = apiKey;
            apiKeyCacheTime = currentTime;

            log.debug("成功获取API_KEY：{}", apiKey.substring(0, 10) + "***");
            return apiKey;

        } catch (Exception e) {
            log.error("获取API_KEY异常", e);
            return null;
        }
    }

    /**
     * 每小时执行一次库存同步任务 - 优化版本
     * 一次性获取所有库存数据，然后在本地匹配更新
     */
//    @Scheduled(cron = "0 0 0/1 * * ?")
    public void syncStockFromMes() {
        log.info("开始执行库存同步定时任务 - 批量优化版本");

        String apiKey = getApiKey();
        if (apiKey == null) {
            log.error("获取API_KEY失败，终止本次库存同步任务");
            return;
        }
        log.info("成功获取API_KEY，开始批量库存同步");

        long startTime = System.currentTimeMillis();
        int totalProcessed = 0;
        int totalUpdated = 0;
        int totalSkipped = 0;
        int totalErrors = 0;

        try {
            // 1. 获取本地所有商品信息
            List<Goods> localGoodsList = goodsMapper.selectList(
                new LambdaQueryWrapper<Goods>().eq(Goods::getIsDelete, 0)
            );
            log.info("本地商品总数: {}", localGoodsList.size());

            // 2. 过滤出有有效标识的商品（barCode或goodsNo不为空）
            List<Goods> validGoodsList = localGoodsList.stream()
                .filter(goods -> {
                    GoodsSku sku = goodsSkuMapper.selectOne(
                        new LambdaQueryWrapper<GoodsSku>()
                            .eq(GoodsSku::getGoodsId, goods.getGoodsId())
                            .last("LIMIT 1")
                    );
                    if (sku == null) {
                        return false;
                    }
                    String barCode = goods.getBarCode();
                    String goodsNo = sku.getGoodsNo();
                    return barCode != null || goodsNo != null;
                })
                .collect(Collectors.toList());

            log.info("有效商品总数（有barCode或goodsNo）: {}", validGoodsList.size());

            if (validGoodsList.isEmpty()) {
                log.warn("没有找到有效商品，结束同步");
                return;
            }

            // 3. 调用远程接口获取批量库存数据
            Map<String, Integer> remoteStockMap = getRemoteStockData(apiKey);
            if (remoteStockMap == null || remoteStockMap.isEmpty()) {
                log.error("获取远程库存数据失败");
                return;
            }

            log.info("成功获取远程库存数据，商品数量: {}", remoteStockMap.size());

            // 4. 本地匹配并更新库存
            for (Goods goods : validGoodsList) {
                try {
                    totalProcessed++;
                    
                    // 检查同步间隔
                    if (!shouldSyncGoods(goods.getGoodsId())) {
                        totalSkipped++;
                        continue;
                    }

                    GoodsSku sku = goodsSkuMapper.selectOne(
                        new LambdaQueryWrapper<GoodsSku>()
                            .eq(GoodsSku::getGoodsId, goods.getGoodsId())
                            .last("LIMIT 1")
                    );

                    if (sku == null) {
                        totalSkipped++;
                        continue;
                    }

                    String barCode = goods.getBarCode();
                    String goodsNo = sku.getGoodsNo();

                    // 根据barCode或goodsNo匹配远程库存
                    Integer remoteStock = findRemoteStock(remoteStockMap, barCode, goodsNo);

                    if (remoteStock != null) {
                        // 检查库存是否变化
                        Integer currentStockNum = sku.getStockNum();
                        if (!remoteStock.equals(currentStockNum)) {
                            // 更新数据库库存
                            sku.setStockNum(remoteStock);
                            sku.setUpdateTime(System.currentTimeMillis() / 1000);
                            goodsSkuMapper.updateById(sku);

                            // 更新同步缓存
                            updateSyncCache(goods.getGoodsId(), remoteStock);

                            totalUpdated++;
                            log.info("商品 {} 库存已更新: {} -> {}", goods.getGoodsId(), currentStockNum, remoteStock);
                        } else {
                            // 库存没变化，也要更新同步时间
                            updateSyncCache(goods.getGoodsId(), remoteStock);
                            totalSkipped++;
                            log.debug("商品 {} 库存未变化，当前库存: {}", goods.getGoodsId(), currentStockNum);
                        }
                    } else {
                        totalSkipped++;
                        log.debug("未找到匹配的远程库存 - 商品ID: {}, barCode: {}, goodsNo: {}",
                                goods.getGoodsId(), barCode, goodsNo);
                    }

                } catch (Exception e) {
                    totalErrors++;
                    log.error("更新商品库存失败 - 商品ID: {}, 错误: {}", goods.getGoodsId(), e.getMessage());
                }
            }

            long duration = System.currentTimeMillis() - startTime;
            log.info("批量库存同步任务完成，耗时: {}ms，处理商品数: {}，更新库存数: {}，跳过数: {}，错误数: {}",
                duration, totalProcessed, totalUpdated, totalSkipped, totalErrors);

        } catch (Exception e) {
            log.error("批量库存同步定时任务执行失败", e);
        }
    }

    /**
     * 调用远程接口获取所有商品的库存数据
     * 返回格式: Map<标识, 库存数量> 其中标识可以是barCode或goodsNo
     */
    private Map<String, Integer> getRemoteStockData(String apiKey) {
        try {
            log.info("调用远程接口获取批量库存数据...");

            // 调用新的批量接口
            String response = ApiHttpClient.get("/v1/api/mes/getAllTotalNum",
                                               SYSTEM_NAME,
                                               apiKey);

            if (response == null || response.trim().isEmpty()) {
                log.error("远程接口返回空响应");
                return null;
            }

            JSONObject jsonResponse = JSONUtil.parseObj(response);
            if (jsonResponse.getInt("code") != 200) {
                log.error("远程接口返回错误: {}", jsonResponse.getStr("msg"));
                return null;
            }

            // 解析返回的数据，转换为Map格式便于查找
            Map<String, Integer> stockMap = new HashMap<>();
            Object data = jsonResponse.get("data");

            if (data instanceof JSONArray) {
                JSONArray stockArray = (JSONArray) data;
                log.info("远程接口返回数据条数: {}", stockArray.size());
                
                for (Object item : stockArray) {
                    if (item instanceof JSONObject) {
                        JSONObject stockItem = (JSONObject) item;
                        String barCode = stockItem.getStr("barCode");
                        String goodsNo = stockItem.getStr("goodsNo");
                        Integer stockNum = stockItem.getInt("stockNum");

                        // 以不同key存储，便于匹配
                        if (barCode != null && !barCode.trim().isEmpty()) {
                            stockMap.put("barcode_" + barCode.trim(), stockNum);
                        }
                        if (goodsNo != null && !goodsNo.trim().isEmpty()) {
                            stockMap.put("goodsno_" + goodsNo.trim(), stockNum);
                        }
                    }
                }
            }

            log.info("成功解析远程库存数据，有效记录数: {}", stockMap.size());
            return stockMap;

        } catch (Exception e) {
            log.error("获取远程库存数据异常: {}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 根据barCode或goodsNo查找远程库存
     */
    private Integer findRemoteStock(Map<String, Integer> remoteStockMap, String barCode, String goodsNo) {
        // 优先按barCode匹配
        if (barCode != null && !barCode.trim().isEmpty()) {
            Integer stock = remoteStockMap.get("barcode_" + barCode.trim());
            if (stock != null) {
                return stock;
            }
        }

        // 如果barCode没找到，按goodsNo匹配
        if (goodsNo != null && !goodsNo.trim().isEmpty()) {
            Integer stock = remoteStockMap.get("goodsno_" + goodsNo.trim());
            if (stock != null) {
                return stock;
            }
        }

        return null;
    }

    /**
     * 检查商品是否应该同步（基于时间间隔）
     */
    private boolean shouldSyncGoods(Long goodsId) {
        String lastSyncTimeKey = "stock:sync:last_time:" + goodsId;
        Long lastSyncTime = redisUtil.get(lastSyncTimeKey, Long.class);

        if (lastSyncTime != null) {
            long currentTime = System.currentTimeMillis() / 1000; // 转换为秒
            long timeDiff = currentTime - lastSyncTime;
            long intervalSeconds = SYNC_INTERVAL_MINUTES * 60;

            if (timeDiff < intervalSeconds) {
                log.debug("商品 {} 距离上次同步不足 {} 分钟，跳过", goodsId, SYNC_INTERVAL_MINUTES);
                return false;
            }
        }

        return true;
    }

    /**
     * 更新同步缓存信息
     *
     * @param goodsId 商品ID
     * @param stockNum 当前库存数量
     */
    private void updateSyncCache(Long goodsId, Integer stockNum) {
        try {
            long currentTime = System.currentTimeMillis() / 1000;

            // 更新最后同步时间
            String lastSyncTimeKey = "stock:sync:last_time:" + goodsId;
            redisUtil.set(lastSyncTimeKey, currentTime, 24, TimeUnit.HOURS); // 24小时过期

            // 更新最后同步的库存值
            String lastSyncValueKey = "stock:sync:last_value:" + goodsId;
            redisUtil.set(lastSyncValueKey, stockNum, 24, TimeUnit.HOURS);

        } catch (Exception e) {
            log.warn("更新同步缓存失败，商品ID: {}", goodsId, e);
        }
    }

    /**
     * 获取商品的最后同步库存值（可选方法，用于业务查询）
     *
     * @param goodsId 商品ID
     * @return 最后同步的库存值，如果没有则返回null
     */
    public Integer getLastSyncStockNum(Long goodsId) {
        String key = "stock:sync:last_value:" + goodsId;
        return redisUtil.get(key, Integer.class);
    }

    /**
     * 测试API_KEY获取功能
     *
     * @return API_KEY获取结果
     */
    public String testApiKeyRetrieval() {
        log.info("开始测试API_KEY获取功能");

        try {
            String apiKey = getApiKey();
            if (apiKey != null) {
                log.info("API_KEY获取成功：{}", apiKey.substring(0, 10) + "***");
                return "SUCCESS: " + apiKey;
            } else {
                log.error("API_KEY获取失败");
                return "FAILED: null";
            }
        } catch (Exception e) {
            log.error("API_KEY获取异常", e);
            return "ERROR: " + e.getMessage();
        }
    }

    /**
     * 强制同步指定商品的库存（手动触发）
     *
     * @param goodsId 商品ID
     * @return 是否同步成功
     */
    public boolean forceSyncStock(Long goodsId) {
        log.info("开始强制同步商品库存: {}", goodsId);

        Goods goods = goodsMapper.selectById(goodsId);
        if (goods == null || goods.getIsDelete() == 1) {
            log.warn("商品 {} 不存在或已删除", goodsId);
            return false;
        }

        try {
            // 为强制同步单独获取API_KEY
            String apiKey = getApiKey();
            if (apiKey == null) {
                log.error("获取API_KEY失败，无法强制同步商品 {}", goodsId);
                return false;
            }

            // 获取远程库存数据
            Map<String, Integer> remoteStockMap = getRemoteStockData(apiKey);
            if (remoteStockMap == null || remoteStockMap.isEmpty()) {
                log.error("获取远程库存数据失败，无法强制同步商品 {}", goodsId);
                return false;
            }

            // 获取商品SKU信息
            GoodsSku sku = goodsSkuMapper.selectOne(
                new LambdaQueryWrapper<GoodsSku>()
                    .eq(GoodsSku::getGoodsId, goodsId)
                    .last("LIMIT 1")
            );

            if (sku == null) {
                log.warn("商品 {} 没有找到SKU信息", goodsId);
                return false;
            }

            String barCode = goods.getBarCode();
            String goodsNo = sku.getGoodsNo();

            if (barCode == null && goodsNo == null) {
                log.warn("商品 {} barCode和goodsNo都为空", goodsId);
                return false;
            }

            // 根据barCode或goodsNo匹配远程库存
            Integer remoteStock = findRemoteStock(remoteStockMap, barCode, goodsNo);

            if (remoteStock != null) {
                // 检查库存是否变化
                Integer currentStockNum = sku.getStockNum();
                if (!remoteStock.equals(currentStockNum)) {
                    // 更新数据库库存
                    sku.setStockNum(remoteStock);
                    sku.setUpdateTime(System.currentTimeMillis() / 1000);
                    goodsSkuMapper.updateById(sku);

                    // 更新同步缓存
                    updateSyncCache(goodsId, remoteStock);

                    log.info("强制同步成功 - 商品 {} 库存已更新: {} -> {}", goodsId, currentStockNum, remoteStock);
                    return true;
                } else {
                    // 库存没变化，也要更新同步时间
                    updateSyncCache(goodsId, remoteStock);
                    log.info("强制同步完成 - 商品 {} 库存未变化，当前库存: {}", goodsId, currentStockNum);
                    return true;
                }
            } else {
                log.warn("强制同步失败 - 未找到匹配的远程库存，商品ID: {}, barCode: {}, goodsNo: {}",
                        goodsId, barCode, goodsNo);
                return false;
            }

        } catch (Exception e) {
            log.error("强制同步商品库存失败: {}", goodsId, e);
            return false;
        }
    }
}
